package com.hk.commons;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;

public class JsonUtils {
	private static ObjectMapper objectMapper = new ObjectMapper();
	private static String CHARSET = "utf-8";

	public static <T> String toJson(T t) {
		try {
			return objectMapper.writeValueAsString(t);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static <T> T toBean(String json_s, TypeReference<T> typeReference) {
		try {
			return objectMapper.readValue(json_s, typeReference);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}

	public static <T> T toBean(String json_s, Class<T> clazz) {
		try {
			return objectMapper.readValue(json_s, clazz);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static <T, V> T toBean(String json_s, Class<T> collectionClass,
			Class<V>... elementClasses) throws JsonParseException,
			JsonMappingException, IOException {
		JavaType javaType = objectMapper.getTypeFactory()
				.constructParametricType(collectionClass, elementClasses);
		return objectMapper.readValue(json_s, javaType);
	}

	public static String toJson(JsonNode node) {
		try {
			return objectMapper.writeValueAsString(node);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static <T> JsonNode toJsonObject(String json_s) {
		try {
			return objectMapper.readTree(json_s);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static void getJsonValue(JsonNode node, String[] path,
			List<String> values, int nextIndex) {
		if (isEmpty(node)) {
			return;
		}

		// 是路径的最后就直接取值
		if (nextIndex == path.length) {
			if (node.isArray()) {
				for (int i = 0; i < node.size(); i++) {
					JsonNode child = node.get(i).get(path[nextIndex - 1]);
					if (isEmpty(child)) {
						continue;
					}
					values.add(child.toString());
				}
			} else {
				JsonNode child = node.get(path[nextIndex - 1]);
				if (!isEmpty(child)) {
					values.add(child.toString());
				}
			}
			return;
		}

		// 判断是Node下是集合还是一个节点
		node = node.get(path[nextIndex - 1]);
		if (node.isArray()) {
			for (int i = 0; i < node.size(); i++) {
				getJsonValue(node.get(i), path, values, nextIndex + 1);
			}
		} else {
			getJsonValue(node, path, values, nextIndex + 1);
		}
	}

	/**
	 * 判断对象是否为空
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object obj) {
		boolean result = true;

		if (obj == null) {
			return true;
		}

		if (obj instanceof String) {
			result = (obj.toString().trim().length() == 0)
					|| obj.toString().trim().equals("null");
		} else if (obj instanceof Collection) {
			result = ((Collection) obj).size() == 0;
		} else {
			result = ((obj == null) || (obj.toString().trim().length() < 1)) ? true
					: false;
		}

		return result;
	}

	/**
	 * 将json字段中每个值用URLEncoder编码 ,将值为null的字段置为空字符串
	 * 
	 * @throws Exception
	 */
	public static String encodeJsonValue(JsonNode parentNode) throws Exception {
		if (parentNode.isNull())
			return "";

		if (parentNode instanceof ArrayNode) {
			for (int i = 0; i < parentNode.size(); i++) {
				encodeJsonValue(parentNode.get(i));
			}
		} else {
			Iterator<Map.Entry<String, JsonNode>> entryItr = parentNode
					.getFields();
			while (entryItr.hasNext()) {
				Map.Entry<String, JsonNode> entry = entryItr.next();
				String subKey = entry.getKey();
				JsonNode subNode = entry.getValue();
				if (subNode.isNull()) {
					((ObjectNode) parentNode).put(subKey, "");
					continue;
				}

				if (subNode instanceof ObjectNode
						|| subNode instanceof ArrayNode) {
					encodeJsonValue(subNode);
				} else {
					((ObjectNode) parentNode).put(subKey,
							URLEncoder.encode(subNode.asText(), CHARSET));
				}
			}
		}

		return JsonUtils.toJson(parentNode);

	}

	/**
	 * 将json字段中每个值用URLDecoder编码 ,将值为null的字段置为空字符串
	 * 
	 * @throws Exception
	 */
	public static String decodeJsonValue(JsonNode parentNode) throws Exception {
		if (parentNode.isNull())
			return "";

		if (parentNode instanceof ArrayNode) {
			for (int i = 0; i < parentNode.size(); i++) {
				decodeJsonValue(parentNode.get(i));
			}
		} else {
			Iterator<Map.Entry<String, JsonNode>> entryItr = parentNode
					.getFields();
			while (entryItr.hasNext()) {
				Map.Entry<String, JsonNode> entry = entryItr.next();
				String subKey = entry.getKey();
				JsonNode subNode = entry.getValue();
				if (subNode.isNull()) {
					// ((ObjectNode) parentNode).put(subKey, "");
					continue;
				}

				if (subNode instanceof ObjectNode
						|| subNode instanceof ArrayNode) {
					decodeJsonValue(subNode);
				} else {
					String newValue = subNode.asText();
					try {
						newValue = URLDecoder.decode(subNode.asText(), CHARSET);
					} catch (UnsupportedEncodingException ex) {
					}

					((ObjectNode) parentNode).put(subKey, newValue);
				}
			}
		}

		return JsonUtils.toJson(parentNode);

	}
}
